/**
 * TagSpaces - universal file and folder organizer
 * Copyright (C) 2017-present TagSpaces GmbH
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License (version 3) as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */

import InfoIcon from '-/components/InfoIcon';
import TsButton from '-/components/TsButton';
import TsSelect from '-/components/TsSelect';
import TsTextField from '-/components/TsTextField';
import TsDialogActions from '-/components/dialogs/components/TsDialogActions';
import TsDialogTitle from '-/components/dialogs/components/TsDialogTitle';
import { useCurrentLocationContext } from '-/hooks/useCurrentLocationContext';
import { useNotificationContext } from '-/hooks/useNotificationContext';
import { useOpenedEntryContext } from '-/hooks/useOpenedEntryContext';
import { openUrl } from '-/services/utils-io';
import { generateClipboardLink } from '-/utils/dom';
import Dialog from '@mui/material/Dialog';
import DialogContent from '@mui/material/DialogContent';
import InputAdornment from '@mui/material/InputAdornment';
import MenuItem from '@mui/material/MenuItem';
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
import { extractTitle } from '@tagspaces/tagspaces-common/paths';
import Links from 'assets/links';
import { ChangeEvent, useEffect, useReducer, useRef } from 'react';
import { useTranslation } from 'react-i18next';
import { QRCode } from 'react-qrcode-logo';

interface Props {
  open: boolean;
  path?: string;
  onClose: () => void;
}

function LinkGeneratorDialog(props: Props) {
  const { open, onClose, path } = props;
  const { t } = useTranslation();
  const { findLocation, currentLocation } = useCurrentLocationContext();
  const { openedEntry } = useOpenedEntryContext();
  const { showNotification } = useNotificationContext();
  const linkValidityDuration = useRef<number>(60 * 15);
  const signedLink = useRef<string>(undefined);
  const [ignored, forceUpdate] = useReducer((x) => x + 1, 0, undefined);
  const theme = useTheme();
  const smallScreen = useMediaQuery(theme.breakpoints.down('md'));

  let location = findLocation(openedEntry?.locationID);
  if (!location) {
    location = currentLocation;
  }
  const gPath = path || openedEntry.path;

  useEffect(() => {
    setSignedLink();
  }, []);

  function setSignedLink() {
    location
      .generateURLforPath(gPath, linkValidityDuration.current)
      .then((url) => {
        signedLink.current = url;
        forceUpdate();
      });
  }

  return (
    <Dialog
      open={open}
      onClose={onClose}
      fullScreen={smallScreen}
      keepMounted
      scroll="paper"
      style={{ marginTop: 12 }}
    >
      <TsDialogTitle
        dialogTitle={t('core:downloadLink')}
        closeButtonTestId="closeLinkGeneratorTID"
        onClose={onClose}
      />
      <DialogContent style={{ overflow: 'auto', height: 450 }}>
        <TsSelect
          label={
            <>
              {t('core:linkValidity')}
              <InfoIcon tooltip={t('core:linkValidityTooltip')} />
            </>
          }
          value={linkValidityDuration.current}
          onChange={(event: ChangeEvent<HTMLInputElement>) => {
            linkValidityDuration.current = parseInt(event.target.value, 10);
            setSignedLink();
          }}
        >
          <MenuItem value={60 * 15}>15 {t('core:minutes')}</MenuItem>
          <MenuItem value={60 * 60}>60 {t('core:minutes')}</MenuItem>
          <MenuItem value={60 * 60 * 24}>1 {t('core:day')}</MenuItem>
          <MenuItem value={60 * 60 * 24 * 3}>3 {t('core:days')}</MenuItem>
          <MenuItem value={60 * 60 * 24 * 7}>7 {t('core:days')}</MenuItem>
        </TsSelect>
        <TsTextField
          name="path"
          slotProps={{
            input: {
              readOnly: true,
              endAdornment: (
                <InputAdornment position="start">
                  <TsButton
                    data-tid="copySharingLinkTID"
                    variant="contained"
                    onClick={() => {
                      const entryTitle = extractTitle(
                        gPath,
                        true,
                        location.getDirSeparator(),
                      );
                      const clipboardItem = generateClipboardLink(
                        signedLink.current,
                        entryTitle,
                      );
                      navigator.clipboard.write(clipboardItem).then(() => {
                        showNotification(t('core:linkCopied'));
                      });
                    }}
                  >
                    {t('core:copy')}
                  </TsButton>
                </InputAdornment>
              ),
            },
          }}
          label={t('core:downloadLink')}
          value={signedLink.current}
        />
        <TsTextField
          name="path"
          label={t('core:qrCode')}
          value={' '}
          slotProps={{
            input: {
              readOnly: true,
              style: { height: 380 },
              startAdornment: (
                <InputAdornment title={t('core:qrCode')} position="start">
                  <QRCode
                    id="qr-code-link"
                    value={signedLink.current}
                    size={350}
                    enableCORS={true}
                    // logoWidth={64}
                    // logoHeight={64}
                    // logoImage=""
                  />
                </InputAdornment>
              ),
            },
          }}
        />
      </DialogContent>
      <TsDialogActions
        style={{
          justifyContent: 'space-between',
        }}
      >
        <TsButton
          data-tid="helpSearchButtonTID"
          onClick={() => {
            openUrl(Links.documentationLinks.sharing);
          }}
        >
          {t('help')}
        </TsButton>
        <TsButton data-tid="closeLinkTID" onClick={onClose}>
          {t('core:close')}
        </TsButton>
      </TsDialogActions>
    </Dialog>
  );
}

export default LinkGeneratorDialog;
